import Foundation

///  函数相关

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}

func greetAgain(person: String) -> String {
    return "Hello again, " + person + "!"
}

// 多参数函数
func greet(person: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return greetAgain(person: person)
    } else {
        return greet(person: person)
    }
}


// MARK: - 多重返回值函数
/// 本质是分会一个元组
func minMax(array: [Int]) -> (min: Int, max: Int)? {
    
    if array.isEmpty {
        return nil
    }
    
    var min = array[0]
    var max = array[0]
    for value in 1..<array.count {
        if value < min {
            min = value
        } else if value > max {
            max = value
        }
    }
    return (min, max)
}

// MARK: - 隐式的返回值
/// 如果一个函数的整个函数体是一个单行表达式, 就可以隐式的返回这个表达式
func greeting(for person: String) -> String {
    "hello, " + person + "!"
}

// MARK: - 函数的参数标签和参数名称
/// argumentLable 为参数标签
/// parameterName 为参数名称
func someFunction(argumentLable parameterName: Int) {
    
}


// MARK: - 默认参数
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    
}


// MARK: - 可变参数
/// 可变参数可以接受0-n个值
func arthmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}


// MARK: - 输入输出参数
/// 函数参数默认是常量, 不可修改
/// 这是可以使用inout关键字
func swapTowInts(_ a: inout Int, _ b: inout Int) {
    let temp = a
    a = b
    b = temp
}


// MARK: - 函数类型
/// 每个函数都有特定的函数类型
/// 函数类型由  `参数类型` + `返回值类型` 组成
func addTwoInts(_ a:Int, _ b: Int) -> Int {
    a + b
}

func mutiplyTwoInts(_ a: Int, _ b: Int) -> Int {
    a * b
}

// 以上两个函数的类型为`(Int, Int) -> Int`

func printHelloWorld() {
    print("hello, world")
}
// 以上函数的类型为`() -> Void`


// MARK: - 使用函数类型
func useFuncTypeDemo() {
    let mathFunction: (Int, Int) -> Int = addTwoInts
    let result = mathFunction(1, 2)
    print("result: \(result)")
}


// MARK: - 函数类型作为参数类型
func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("result: \(mathFunction(a, b))")
}
/// 将函数类型作为参数类型
public func funcDemo_printMathResult() {
    printMathResult(mutiplyTwoInts, 3, 5)
}



// MARK: - 将函数类型作为返回值
func stepForward(_ input: Int) -> Int {
    input + 1
}

func stepBackward(_ input: Int) -> Int {
    input - 1
}

func chooseStepFunction(backward: Bool) -> ((Int) -> Int) {
    return backward ? stepBackward : stepForward
}

public func funcDemo_useFuncAsRes() {
    let current = 3
    let moveNearerToZero = chooseStepFunction(backward: current > 0)(current)
    print("old:\(current) new:\(moveNearerToZero)")
}



// MARK: - 嵌套函数
func chooseStepFunction2(backward: Bool) -> ((Int) -> Int) {
    func stepForward(input: Int) -> Int { input + 1 }
    func stepBackward(input: Int) -> Int { input - 1 }
    return backward ? stepBackward : stepForward
}


